package com.bwie.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.mapper.TbMenuMapper;
import com.bwie.pojo.TbMenu;
import com.bwie.pojo.TbUser;
import com.bwie.service.TbUserService;
import com.bwie.mapper.TbUserMapper;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import com.bwie.vo.LoginInfoVo;
import com.bwie.vo.PageInfoVo;
import com.bwie.vo.RegInfoVo;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* @author 31803
* @description 针对表【tb_user(用户表)】的数据库操作Service实现
* @createDate 2025-07-18 15:06:50
*/
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser>
    implements TbUserService{


    @Autowired
    TbUserMapper tbUserMapper;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    TbMenuMapper tbMenuMapper;

    @Override
    public R sendCode(String mobile) {
        boolean mobile1 = Validator.isMobile(mobile);
        if(!mobile1){
            return R.ERROR(500,"用户手机号格式不正确");
        }
        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserMobile, mobile));

        String code = RandomUtil.randomNumbers(4);

        MobileMessageUtil.sendMobileMessage(mobile,code);
        redisTemplate.opsForValue().set(mobile,code,5, TimeUnit.MINUTES);

        return R.OK(code);
    }

    @Override
    public R userReg(RegInfoVo regInfoVo) {
        //验证手机号是否存在
        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserMobile, regInfoVo.getMobile()));
        if(tbUser!=null){
            return R.ERROR(500,"用户已注册");
        }

        //校验验证码
        String rediscode = redisTemplate.opsForValue().get(regInfoVo.getMobile());
        if(rediscode==null){
            return R.ERROR(500,"验证码已经过期");
        }

        if(!regInfoVo.getCode().equals(rediscode)){
            return R.ERROR(500,"验证码不正确");
        }
        //加密密码
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(regInfoVo.getPassword());
        //用户注册
        TbUser tbUser1 = new TbUser();
        tbUser1.setUserPass(encode);
        tbUser1.setUserMobile(regInfoVo.getMobile());
        tbUser1.setUserName("匿名登录");
        tbUser1.setCreateTime(new Date());
        tbUser1.setCreateBy("管理员");
        tbUserMapper.insert(tbUser1);

        return R.OK();
    }

    @Override
    public R login(LoginInfoVo loginInfoVo) {
        //检查用户是否存在
        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>()
                .lambda().eq(TbUser::getUserMobile, loginInfoVo.getMobile()));
        if(tbUser==null){
            return R
                    .ERROR(500,"用户不存在");
        }

        String key1="login"+tbUser.getUserId();
        String key2="lock"+tbUser.getUserId();
        long increment =1;
        Integer total= 3;
        if(redisTemplate.hasKey(key2)){
            return R.ERROR(500,"错误次数已经操作三次请一分钟后再试");
        }
        //检查密码是否正确
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        boolean matches = bCryptPasswordEncoder.matches(loginInfoVo.getPassword(), tbUser.getUserPass());
        if(!matches){
            Boolean hasKey = redisTemplate.hasKey(key1);
            if(hasKey){

                 increment = redisTemplate.opsForValue().increment(key1);
                if(increment>3){
                    redisTemplate.delete(key1);
                    redisTemplate.opsForValue().set(key2,"1",3,TimeUnit.MINUTES);
                    return R.ERROR(500,"错误次数已经操作三次请一分钟后再试");
                }
            }else{
                redisTemplate.opsForValue().set(key1,"1",5,TimeUnit.MINUTES);
            }


            return R.ERROR(500,"用户密码不正确还有"+(total-increment)+"次");
        }

        //生成token
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "123456")
                .claim("userId", tbUser.getUserId())
                .claim("userMobile", tbUser.getUserMobile())
                .compact();
        tbUser.setToken(token);
        //存入token
        redisTemplate.opsForValue().set(token,token,5,TimeUnit.HOURS);
        //返回用户信息
        //获取用户角色
       List<String> roleList= tbUserMapper.selectRole(tbUser.getUserId());
       tbUser.setRoleList(roleList);
        //获取当前用户的权限
      List<TbMenu> tbMenuList= tbUserMapper.selectMenuList(tbUser.getUserId());
        tbUser.setMenuList(tbMenuList);
        return R.OK(tbUser);
    }

    @Override
    public R getTreeMenu() {

        List<TbMenu> tbMenus = tbMenuMapper.selectList(null);
        List<Tree<String>> menuTree = TreeUtil.build(tbMenus, "0", (menu, tree) -> {
            tree.setId(menu.getMenuId() + "");
            tree.setName(menu.getMenuName());
            tree.setParentId(menu.getMenuPid() + "");
            tree.putExtra("menuPath", menu.getMenuPath());
            tree.putExtra("menuTitle", menu.getMenuTitle());
        });


        return R.OK(menuTree);
    }

    @Override
    public R getShopperList(PageInfoVo pageInfoVo) {

        //构造分页
        Page<TbUser> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        //构造查询条件

        Page<TbUser> tbUserPage = tbUserMapper.selectShopPage(page,pageInfoVo);
        return R.OK(tbUserPage);
    }

}




